home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Practical Algorithms for Image Analysis
/
Practical Algorithms for Image Analysis.iso
/
CH_2.2
/
HISTEX
/
HISTEX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1999-09-11
|
6KB
|
190 lines
/*
* histstats.c
*
* Practical Algorithms for Image Analysis
*
* Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
*/
/* HISTEX: program performs histogram expansion upon a b/w image - removing
* the tails of the probability density function and expanding that
* function to the entire range, where <hiValue> is the max intensity
* usage: histex inimg outimg [-p PCT_KEEP] [-m MAXVAL] [-L]
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <tiffimage.h> /* tiff info on images */
#include <images.h>
extern void print_sos_lic ();
#define NBINS 256 /* no. of histogram bins */
#define PCT_KEEP 98.0 /* percentage of histogram to keep */
int usage (short);
int input (int, char **, double *, long *);
int histogram (char *, int, int *);
main (argc, argv)
int argc;
char *argv[];
{
Image *imgI; /* I/O image structure */
unsigned char **image; /* input/output image */
double pctKeep; /* percent of histogram to keep */
double tail, /* percent of histogram tail to remove */
expand, /* factor for histogram expansion */
value; /* pixel value after hist. expansion */
long nTotal, /* total no. of elements in image */
hiValue, /* high intensity value */
nRemove, /* no. pixels to remove in hist. tail */
sum, /* running sum of pixels in tail */
shift, /* shift (down to zero) for hist. exp. */
top, /* top value for expansion */
i, j;
int hist[NBINS]; /* image histogram array */
struct point imgSize; /* image dimensions */
/* read user parameter values */
if ((input (argc, argv, &pctKeep, &hiValue)) < 0)
return (-1);
tail = (100.0 - pctKeep) / 2.0;
/* open image */
imgI = ImageIn (argv[1]);
if (imgI->bps == 8 && imgI->spp == 3) {
printf ("Got RGB image!!!\nInput image must be Grayscale or B&W!!\n");
exit (1);
}
image = imgI->img;
imgSize.y = ImageGetHeight (imgI);
imgSize.x = ImageGetWidth (imgI);
printf ("image size is %dx%d\n", imgSize.x, imgSize.y);
/* zero histogram array */
for (i = 0; i < NBINS; i++)
hist[i] = 0;
/* construct histogram */
for (j = 0, nTotal = 0; j < imgSize.y; j++) {
nTotal += imgSize.x;
histogram (image[j], imgSize.x, hist);
}
nRemove = (int) (nTotal * tail / 100.0);
/* find lower tail */
for (i = 0, sum = 0; i < NBINS; i++) {
sum += hist[i];
if (sum >= nRemove)
break;
}
shift = i;
/* find upper tail */
for (i = NBINS - 1, sum = 0; i > 0; --i) {
sum += hist[i];
if (sum >= nRemove)
break;
}
top = i;
expand = (double) (hiValue) / (double) (top - shift + 1);
printf ("Tails: %d, %d. Histogram expansion = %5.2f.\n",
shift, top, expand);
/* do histogram expansion on input data and write output */
for (j = 0; j < imgSize.y; j++) {
for (i = 0; i < imgSize.x; i++) {
value = (((double) image[j][i]) - shift) * expand;
if (value < 0.0)
value = 0.0;
else if (value > hiValue)
value = hiValue;
image[j][i] = (unsigned char) value;
}
}
ImageOut (argv[2], imgI);
return (0);
}
/* USAGE: function gives instructions on usage of program
* usage: usage (flag)
* When flag is 1, the long message is given, 0 gives short.
*/
int
usage (flag)
short flag; /* flag =1 for long message; =0 for short message */
{
/* print short usage message or long */
printf ("USAGE: histex inimg outimg [-p PCT_KEEP] [-m MAXVAL] [-L]\n");
if (flag == 0)
return (-1);
printf ("\nhistex enhances image contrast by performing\n");
printf ("histogram expansion.\n\n");
printf ("ARGUMENTS:\n");
printf (" inimg: input image filename (TIF)\n");
printf (" outimg: output image filename (TIF)\n\n");
printf ("OPTIONS:\n");
printf (" -p PCT_KEEP: percent of histogram to keep. Tails at upper\n");
printf (" and lower of histogram are removed equally.\n");
printf (" (default = %d%%)\n", (long) PCT_KEEP);
printf (" -m MAXVALUE: maximum value of image intensity (if different\n");
printf (" than 255), default = %d\n", NBINS - 1);
printf (" -L: print Software License for this module\n");
return (-1);
}
/* INPUT: function reads input parameters
* usage: input (argc, argv, pctKeep, hiValue)
*/
#define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
int
input (argc, argv, pctKeep, hiValue)
int argc;
char *argv[];
double *pctKeep; /* percentage of histogram to keep */
long *hiValue; /* maximum output intensity value */
{
long n;
if (argc == 1)
USAGE_EXIT (1);
if (argc == 2)
USAGE_EXIT (0);
*pctKeep = PCT_KEEP;
*hiValue = NBINS - 1;
for (n = 3; n < argc; n++) {
if (strcmp (argv[n], "-p") == 0) {
if (++n == argc || argv[n][0] == '-')
USAGE_EXIT (0);
*pctKeep = (double) atol (argv[n]);
}
else if (strcmp (argv[n], "-m") == 0) {
if (++n == argc || argv[n][0] == '-')
USAGE_EXIT (0);
*hiValue = atol (argv[n]);
}
else if (strcmp (argv[n], "-L") == 0) {
print_sos_lic ();
exit (0);
}
else
USAGE_EXIT (0);
}
return (0);
}